/**************************************************************************
FixApi.h

FixApi header file.

LiveDTP SDK for client connections(C++)

Copyright (c) ApexSoft. All Rights Reserved.
**************************************************************************/
#ifndef __APEX_FIXAPI_H__
#define __APEX_FIXAPI_H__

#include <string>

#ifdef USE_STATIC_FIXAPI
#define FIX_API_EXPORT
#define NS_FIXAPI_EXPORT_BEGIN \
    namespace fixapi5x         \
    {
#define NS_FIXAPI_EXPORT_END }
#else
#ifndef FIX_API_EXPORT
#ifndef _MSC_VER
#define FIX_API_EXPORT extern "C"
#else
#define FIX_API_EXPORT __declspec(dllimport)
#endif
#endif
#define NS_FIXAPI_EXPORT_BEGIN
#define NS_FIXAPI_EXPORT_END
#endif

#ifndef _MSC_VER
#if __i386 || __i386__
#define FIX_INT64 long long
#else
#define FIX_INT64 long
#endif
#define HANDLE_ID long
#else
#define FIX_INT64 __int64
#ifdef WIN64
#define HANDLE_ID __int64
#else
#define HANDLE_ID int
#endif
#endif

#define HANDLE_CONN HANDLE_ID
#define HANDLE_SESSION HANDLE_ID
#define HANDLE_SVC HANDLE_ID

#ifndef FIX_PUBLISH_TYPE_DEF
#define FIX_PUBLISH_TYPE_DEF
enum FIX_PUBLISH_TYPE
{
    FIX_PUB_TYPE_COMM = 0,
    FIX_PUB_TYPE_RESUBS_BEFORE = 1, // for Fix_SetPubPacketId/SetSubsCondi
    FIX_PUB_TYPE_RESUBS_AFTER_SUCC = 2,
    FIX_PUB_TYPE_RESUBS_AFTER_FAIL = 3,
    FIX_PUB_TYPE_DOWN = 4
};
#endif

NS_FIXAPI_EXPORT_BEGIN
/*
函数名称: Fix_AutoLoadOpenSSL

函数说明:
    表示接口库内部是否需要自动初始化OpenSSL，默认为初始化。
    要求在Fix_Initialize之前调用。
    如果外部应用程序已经加载，则需要调用这个函数禁用自动初始化OpenSSL。
    针对一些应用系统本身已经初始化OpenSSL的情况下，再调用Fix_Initialize出错，建议先调用此函数。
    如果应用系统本身未初始化OpenSSL的情况，无须调用此函数。

参数说明:
    bLoad  -- [in] 是否需要加载OpenSSL, true=加载, false=不加载

返回数据:
    true   -- 调用成功
    false  -- 调用失败，可以获取错误信息
*/
FIX_API_EXPORT bool Fix_AutoLoadOpenSSL(bool bLoad);

/*
函数名称: Fix_Initialize

函数说明:
    第三方接口库初始化。只要调用一次就可以，不能多次调用。
    要求在其他函数调用之前执行初始化（在Fix_AutoLoadOpenSSL后面执行）

返回数据:
    true   -- 初始化成功
*/
FIX_API_EXPORT bool Fix_Initialize();

FIX_API_EXPORT bool Fix_SetCharset(const char *pszEncode);

// 第三方接口库卸载。
// 只要调用一次就可以，不能多次调用，要求在最后退出或不使用时调用
FIX_API_EXPORT bool Fix_Uninitialize();

// 设置第三方软件名称和版本
FIX_API_EXPORT bool Fix_SetAppInfo(const char *sAppName, const char *sVer);

/*
函数名称: Fix_SetDefaultInfo

函数说明:
    设置每个业务请求包缺省的头信息

参数说明:
    sOperator(sUser)          -- [in] 系统要求的柜员代码(八位的字符串)
    sEntrustWay(sWTFS)        -- [in] 委托方式
    sSrcBranchId(sFBDM)       -- [in] 发生营业部的代码信息(四位的字符串)
    sDestBranchId(sDestFBDM)  -- [in] 目标营业部的代码信息(四位的字符串)

返回数据:
    true      -- 表示成功
    false     -- 表示失败
*/
FIX_API_EXPORT bool Fix_SetDefaultInfo(const char *sOperator, const char *sEntrustWay, const char *sSrcBranchId, const char *sDestBranchId);

/*
函数名称: Fix_SetProxy

函数说明:
    设置代理连接参数，需要在Fix_Connect之前调用

参数说明:
    nType     -- [in] 代理类型，取值如下
                      -- 0   // 不使用代理服务器
                      -- 4   // SOCKET4代理(x)
                      -- 5   // SOCKET5代理(x)
                      -- 80  // HTTP代理(x)
    sAddr     -- [in] 代理连接服务器ip地址
    nPort     -- [in] 代理服务器端口
    sUser     -- [in] 代理连接用户名
    sPwd      -- [in] 代理连接密码

返回数据:
    true      -- 设置成功
*/
FIX_API_EXPORT bool Fix_SetProxy(int nType, const char *sAddr, int nPort, const char *sUser, const char *sPwd);

/*
函数名称: Fix_SetCertFile

函数说明:
    设置连接使用的证书，需要在Fix_Connect之前调用。

参数说明：
    sFileCert   -- [in] 客户端证书文件(由客户提供)
    sCertPwd    -- [in] 客户端证书密码
    sProcotol   -- [in] 连接协议
                        -- "SSLv3" // 采用SSLv3协议(x)
                        -- "TLSv1" // 采用TLSv1协议(x)
                        -- ""      // 为空，标准认证方式
                        -- 其他    // 证书标准安全认证方式
    sFileCA     -- [in] 信任证书文件(一般情况下为空,因为信任证书已经在客户端证书中，除非客户有特别提供)
    bVerify     -- [in] 是否验证服务器证书

返回数据:
    true        -- 返回设置成功
*/
FIX_API_EXPORT bool Fix_SetCertFile(const char *sFileCert, const char *sCertPwd,
                                    const char *sFileCA = "", const char *sProcotol = "", bool bVerify = false);

// 设置传输数据(应答)压缩方式, 支持 std/lz4, 请务必确认后台服务支持lz4(v68.108), 否则可能导致连接失败或不生效
FIX_API_EXPORT bool Fix_SetZipName(const char *sName);

// 设置全局参数, 请务必确认接入服务支持(v69), 否则可能导致连接失败或不生效
//    rsa       通信协商算法, 默认RSA1024, 可选RSA2048/SM2, 证书登录时根据证书决定
//    crypto    通信加密算法, 默认BF, 可选SM4
FIX_API_EXPORT void Fix_SetParamEx(const char *sType, const char *sVal);
/*
函数名称: Fix_Connect

函数说明:
    连接到顶点中间件服务器，建议输入参数可配置。
    多连接地址，会随机选择其中一个做起始连接地址，其他地址将做备机地址。

参数说明:
    sAddr       -- [in] 服务器地址字符串,格式 [ip]@[port]/tcp;[ip]@[port]/tcp 例如:127.0.0.1@9901/tcp;127.0.0.1@8801/tcp
    sUser       -- [in] 通信用户名 (由客户提供,如没有设置通信用户，为空)
    sPwd        -- [in] 通信密码 (由客户提供,如没有设置通信用户，为空)
    timeout_sec -- [in] 保留(超时时间控制未实现)

返回数据:
    系统返回类型为 HANDLE_CONN 的连接句柄。如果连接失败则返回0; 成功不为0;
*/
FIX_API_EXPORT HANDLE_CONN Fix_Connect(const char *sAddr, const char *sUser = "",
                                       const char *sPwd = "", int timeout_sec = 0);

// user data ptr on connection
FIX_API_EXPORT void Fix_SetConnUserData(HANDLE_CONN hConn, void *pdata);
FIX_API_EXPORT void *Fix_GetConnUserData(HANDLE_CONN hConn);

// server charset gbk or utf8
FIX_API_EXPORT bool Fix_IsServerUTF8Charset(HANDLE_CONN hConn);

// setting transfer mode option
FIX_API_EXPORT bool Fix_SetTranMode(HANDLE_CONN hConn, int nkey, int nval);
// 新增系统全局的备份地址
// 注意：如果一个程序同时连接不同服务器做不同业务，慎用全局备份地址
FIX_API_EXPORT bool Fix_AddBackupSvrAddr(const char *sAddr);
// 单独给某个连接添加备份地址
FIX_API_EXPORT bool Fix_AddConnectionBackupSvr(HANDLE_CONN hConn, const char *sAddr);

// 关闭与顶点中间件的连接
FIX_API_EXPORT bool Fix_Close(HANDLE_CONN conn);

/*
函数名称: Fix_AllocateSession

函数说明:
    根据一个连接句柄分配一个会话句柄，用于数据交互。
    由用户自己在应用层通过调用Fix_AllocateSession分配出来的对象
    必须由用户自己调用Fix_ReleaseSession来释放，反之则不必要。
    原则上遵循“谁分配谁释放”。这样就可以确保内存不泄露。
    一个会话句柄只能做一次业务调用，做完释放，下次业务重新申请会话句柄
    一般约定参数为 sess 代表的是会话句柄

参数说明:
    conn    -- [in] 连接句柄，该句柄由Fix_Connect成功后返回

返回数据:
    NULL    -- 申请会话句柄失败，返回空
    sess    -- 返回会话句柄，非空
*/
FIX_API_EXPORT HANDLE_SESSION Fix_AllocateSession(HANDLE_CONN conn);

// 释放会话句柄
FIX_API_EXPORT bool Fix_ReleaseSession(HANDLE_SESSION sess);

// 设置会话交互的超时时间，系统默认为30秒
FIX_API_EXPORT bool Fix_SetTimeOut(HANDLE_SESSION sess, int timeout_sec);

// 设置会话的委托方式，需要在 Fix_CreateHead 前调用
FIX_API_EXPORT bool Fix_SetWTFS(HANDLE_SESSION sess, const char *sVal);
FIX_API_EXPORT bool Fix_SetEntrustWay(HANDLE_SESSION sess, const char *sVal);

// 设置会话的发生营业部代码(4位代码)，需要在 Fix_CreateHead 前调用
FIX_API_EXPORT bool Fix_SetFBDM(HANDLE_SESSION sess, const char *sVal);
FIX_API_EXPORT bool Fix_SetSrcBranchId(HANDLE_SESSION sess, const char *sVal);

// 设置会话的目标营业部代码(4位代码)，需要在 Fix_CreateHead 前调用
FIX_API_EXPORT bool Fix_SetDestFBDM(HANDLE_SESSION sess, const char *sVal);
FIX_API_EXPORT bool Fix_SetDestBranchId(HANDLE_SESSION sess, const char *sVal);

// 设置会话的业务发生的站点信息，需要在 Fix_CreateHead 前调用
FIX_API_EXPORT bool Fix_SetNode(HANDLE_SESSION sess, const char *sVal);
FIX_API_EXPORT bool Fix_SetOpStation(HANDLE_SESSION sess, const char *sVal);

// 设置会话的业务发生的柜员代码信息，需要在 Fix_CreateHead 前调用
FIX_API_EXPORT bool Fix_SetGYDM(HANDLE_SESSION sess, const char *sVal);
FIX_API_EXPORT bool Fix_SetOperator(HANDLE_SESSION sess, const char *sVal);

// 设置会话的附加用户自定义信息，需要在 Fix_CreateHead 前调用
FIX_API_EXPORT bool Fix_SetUserHeadInfo(HANDLE_SESSION sess, const char *sVal);

/*
函数名称: Fix_CreateHead

函数说明:
    设置会话的业务功能号。
    具体的功能号的定义请参照【第三方接入业务接口文档】。

参数说明:
    sess    -- [in] 会话句柄
    sFunc   -- [in] 系统提供的业务功能号

返回数据:
    true    -- 设置成功
    false   -- 设置失败
*/
FIX_API_EXPORT bool Fix_CreateHead(HANDLE_SESSION sess, const char *sFunc);
FIX_API_EXPORT bool Fix_CreateReq(HANDLE_SESSION sess, const char *sFunc);

/*
函数名称: Fix_SetItem

函数说明:
    设置该会话要发送给中间件的业务的请求域数据 或 服务应答域数据。
    注:( 服务应答域数据只是针对一些中间件业务需要第三处理机处理的情况下使用。
    而且是要求通过注册服务实现; 一般的情况下不使用该方式接入。)

参数说明:
    sess    -- [in] 会话句柄
    id      -- [in] 请求域的tag值(FID)，具体的定义值请参考【第三方接入业务接口文档】
    val     -- [in] 字符串类型，对应FID的业务数据

返回数据:
    true    -- 设置成功
    false   -- 设置失败
*/
FIX_API_EXPORT bool Fix_SetItem(HANDLE_SESSION sess, int id, const char *val);
FIX_API_EXPORT bool Fix_SetString(HANDLE_SESSION sess, int id, const char *val);
FIX_API_EXPORT bool Fix_SetInt(HANDLE_SESSION sess, int id, int val);
FIX_API_EXPORT bool Fix_SetInt64(HANDLE_SESSION sess, int id, FIX_INT64 val);
FIX_API_EXPORT bool Fix_SetLong(HANDLE_SESSION sess, int id, FIX_INT64 val);
FIX_API_EXPORT bool Fix_SetDouble(HANDLE_SESSION sess, int id, double val, int precise = 6);
// 设置会话的 RawData 字段
FIX_API_EXPORT bool Fix_SetItemBuf(HANDLE_SESSION sess, const char *val, int len);

/*
函数名称: Fix_Run

函数说明:
    提交业务数据，并等待全部的业务结果返回。

参数说明:
    sess    -- [in] 会话句柄

返回数据:
    true    -- 通信发出成功
    false   -- 通信发出失败

使用说明:
    参考示例代码,执行Run之后可以通过Fix_GetCode取出错误码判断成功或失败
    通过Fix_GetErrMsg取出错误信息
*/
FIX_API_EXPORT bool Fix_Run(HANDLE_SESSION sess);

// 直接放弃等待业务的应答数据 (在同步方式下使用)
FIX_API_EXPORT bool Fix_Cancel(HANDLE_SESSION sess);

/*
函数名称: Fix_AsyncRun

函数说明:
    异步提交业务数据，不等待待全部的业务结果返回。
    和函数Fix_IsReplyed配合使用.

参数说明:
    sess    -- [in] 会话句柄

返回数据:
    true    -- 通信发出成功
    false   -- 通信发出失败

使用说明:
    参考示例代码, 后续通过Fix_IsReplyed判断是否收到应答(或等待超时)
    通过Fix_GetCode取出错误码判断成功或失败
    通过Fix_GetErrMsg取出错误信息
*/
FIX_API_EXPORT bool Fix_AsyncRun(HANDLE_SESSION sess);

/*
函数名称: Fix_IsReplyed

函数说明:
    异步提交业务数据后，检查数据是否全部返回。

参数说明:
    sess        -- [in] 会话句柄
    timeout_ms  -- [in/option] 指定等待的时间（毫秒），默认不等待。

返回数据:
    true        -- 应答数据全部返回
    false       -- 数据未返回，需要继续等待
*/
FIX_API_EXPORT bool Fix_IsReplyed(HANDLE_SESSION sess, int timeout_ms = -1);

// 读取业务提交返回的错误代码
FIX_API_EXPORT FIX_INT64 Fix_GetCode(HANDLE_SESSION sess);

/*
函数名称: Fix_GetErrMsg

函数说明:
    读取业务提交失败的错误信息。

参数说明:
    sess    -- [in] 会话句柄
    out     -- [in/out] 存放错误信息的缓冲区
                        -- [in] 输入缓冲区，io_len表示送入的缓冲区大小
                        -- [out] 输出错误信息，io_len表示返回的字符串长度
                        如果输入缓冲区大小不够，返回空字符串""，io_len表示期望输入的缓冲区大小
    io_len  -- [in/out] 缓冲区的大小

返回数据:
    out     -- 返回错误信息，直接返回输入缓冲区指针
*/
FIX_API_EXPORT char *Fix_GetErrMsg(HANDLE_SESSION sess, char *out, int &io_len);

// 读取中间件返回的业务应答数据的行数
FIX_API_EXPORT int Fix_GetCount(HANDLE_SESSION sess);

/*
函数名称: Fix_HaveItem

函数说明:
    1、检查中间件的返回结果集的指定行中是否含有指定域。
    2、或者检查中间件请求的业务数据是否含有指定域。

参数说明:
    sess    -- [in] 会话句柄
    id      -- [in] 指定域的tag值，具体的定义值请参考【第三方接入业务接口文档】
    row     -- [in][option] 指定返回数据结果集中的行数(行数索引值以0开始)
                    如果不设置这个值，表示读取第一行的数据。

返回数据:
    true    -- 含有指定的域数据
    false   -- 没有该域数据。
*/
FIX_API_EXPORT bool Fix_HaveItem(HANDLE_SESSION sess, int id, int row = -1);

/*
函数名称: Fix_GetItem

函数说明:
    1、从中间件的返回结果集的指定行中读取业务应答数据。
    2、或者是读取中间件请求的业务请求。

参数说明:
    sess    -- [in] 会话句柄
    id      -- [in] 指定域的tag值，具体的定义值请参考【第三方接入业务接口文档】
    out     -- [in/out] 存放错误信息的缓冲区
                        -- [in] 输入缓冲区，io_len表示送入的缓冲区大小
                        -- [out] 输出字符串，io_len表示返回的字符串长度
    io_len  -- [in/out] 缓冲区的大小
    row     -- [in][option] 指定返回数据结果集中的行数(行数索引值以0开始).
                    如果不设置这个值，表示读取第一行的数据。

返回数据:
    out     -- 返回字符串，直接返回输入缓冲区指针
*/
FIX_API_EXPORT char *Fix_GetItem(HANDLE_SESSION sess, int id, char *out, int &io_len, int row = -1);
FIX_API_EXPORT FIX_INT64 Fix_GetInt64(HANDLE_SESSION sess, int id, int row = -1);
FIX_API_EXPORT FIX_INT64 Fix_GetLong(HANDLE_SESSION sess, int id, int row = -1);
FIX_API_EXPORT double Fix_GetDouble(HANDLE_SESSION sess, int id, int row = -1);
// io_len 输入缓冲区大小，返回长度
FIX_API_EXPORT bool Fix_GetItemBuf(HANDLE_SESSION sess, char *out, int &io_len, int row);

// 订阅回调函数,可以用这个函数读取推送的包序号
FIX_API_EXPORT FIX_INT64 Fix_GetPublishPacketId(HANDLE_SESSION sess, int row = -1);

FIX_API_EXPORT FIX_PUBLISH_TYPE Fix_GetPublishType(HANDLE_SESSION sess);

/*
函数名称: Fix_UniEncode

函数说明:
    A5 统一标准加密，加密类型 (数值: 5)
    注意加密后的长度根据输入内容的长短变化，送入足够的缓冲区大小。

输入参数:
    sKey        -- [in] 用来组合加密密码, 可以是客户号, 资金号, 及其他字符串
    pData       -- [in] 待加密的明文缓冲区
    nDataLen    -- [in] 输入的明文长度，默认为0，自动计算长度
    io_len      -- [in] 输入：pData缓冲区大小
                        输出：加密后的密文长度，若因缓冲区长度不够加密失败，根据这个调整

返回数据:
    pData       -- 加密成功，返回加密后的密文（可显示字符），直接覆盖原来输入的数据（pData）
                -- 加密失败：传入指针为空或缓冲区长度不够，返回空字符串
*/
FIX_API_EXPORT char *Fix_UniEncode(const char *sKey, char *pData, int &io_len, int nDataLen = 0);
// A5 统一标准加密，外围系统使用，加密类型 (数值: 6)
FIX_API_EXPORT char *Fix_UniEncode3rd(const char *sKey, char *pData, int &io_len, int nDataLen = 0);
FIX_API_EXPORT char *Fix_Encode_Old(char *pData);
// A5 信创加密算法, 加密类型 7
FIX_API_EXPORT char *Fix_GMEncode(const char *sKey, char *pData, int &io_len, int nDataLen = 0);
// A5 信创加密算法, 加密类型 8, 外围系统使用
FIX_API_EXPORT char *Fix_GMEncode3rd(const char *sKey, char *pData, int &io_len, int nDataLen = 0);
// A5 信创加密算法, 加密类型 9
FIX_API_EXPORT char *Fix_GMHash(const char *sKey, char *pData, int &io_len, int nDataLen = 0);
// A5 信创加密算法, 加密类型 9, 外围系统使用, 传入{sm3}base64密文
FIX_API_EXPORT char *Fix_GMHash3rd(const char *sKey, char *pData, int &io_len, int nDataLen = 0);
/*
函数名称: Fix_GetToken

函数说明:
    取出对于的令牌字符串(可选、与后台系统配置有关)

参数说明:
    sess    -- [in] 会话句柄
    out     -- [in/out] 缓冲区
                        -- [in] 输入缓冲区，io_len表示送入的缓冲区大小
                        -- [out] 输出字符串，io_len表示返回的字符串长度
返回数据:
    out     -- 返回字符串，直接返回输入缓冲区指针
*/
FIX_API_EXPORT char *Fix_GetToken(HANDLE_SESSION sess, char *out, int &io_len);

// 设置会话的令牌(可选、与后台系统配置有关)
FIX_API_EXPORT bool Fix_SetToken(HANDLE_SESSION sess, const char *val);

// 开启日志功能(默认开启日志功能)
FIX_API_EXPORT bool Fix_WriteLog(bool bWrite);

// 发出应答数据
FIX_API_EXPORT bool Fix_Write(HANDLE_SESSION sess);

/*
函数名称: Fix_SetAutoReconnect

函数说明:
    启用/禁用HANDLE_CONN断线自动重连机制，默认启用
    如果第三方采用自己管理HANDLE_CONN连接, 必须把自动重连关闭，避免不必要的资源浪费
*/
FIX_API_EXPORT bool Fix_SetAutoReconnect(HANDLE_CONN conn, bool bAutoReconnect);

// 获取连接HANDLE_CONN断线自动重连状态
FIX_API_EXPORT bool Fix_GetAutoReconnect(HANDLE_CONN conn);

// 判断连接状态, true连接正常
FIX_API_EXPORT bool Fix_IsConnect(HANDLE_CONN conn);

/*
函数名称: Fix_GetLastErrMsg

函数说明:
    获取错误信息，比如在Fix_Connect或者Fix_ConnectEx失败的时调用

参数说明:
    out     -- [in/out] 缓冲区
                        -- [in] 输入缓冲区，io_len表示送入的缓冲区大小
                        -- [out] 输出字符串，io_len表示返回的字符串长度
返回数据:
    out     -- 返回字符串，直接返回输入缓冲区指针
*/
FIX_API_EXPORT char *Fix_GetLastErrMsg(char *out, int &io_len);

// 设置订阅包序号（从指定包序号开始接收数据，针对MQ可靠消息订阅有效）
FIX_API_EXPORT bool Fix_SetSubsPacketId(HANDLE_SESSION sess, FIX_INT64 nPacketId);
FIX_API_EXPORT FIX_INT64 Fix_GetSubsPacketId(HANDLE_SESSION sess);
/*
函数名称: Fix_SubscribeByCustomer

函数说明:
    面向主交易系统的客户数据订阅函数，在回调函数处理中间件推送的消息
    需要设置令牌验证
    回调函数定义为:
        bool CallBackFunc( HANDLE_CONN conn, HANDLE_SESS sess, int64 nSubs, void *pData )
        -- conn 连接句柄
        -- sess 会话句柄
        -- nSubs 订阅句柄
        -- pData 用户自定义data指针

参数说明:
    sess    -- [in] 会话句柄
    nSubs   -- [out] 返回订阅句柄
    sKHH    -- [in] 订阅的客户号
    pFunc   -- [in] 回调函数指针
    pData   -- [in] 用户自定义data指针（可以为NULL）

返回结果:
    true    -- 订阅成功
    false   -- 订阅失败
*/
FIX_API_EXPORT bool Fix_SubscribeByToken(HANDLE_SESSION sess, FIX_INT64 &nSubs, const char *sKHH, const char *stoken, void *pFunc, void *pData);

FIX_API_EXPORT bool Fix_SubscribeByCustomer(HANDLE_SESSION sess, FIX_INT64 &nSubs, const char *sKHH, const char *sPwd, void *pFunc, void *pData);

FIX_API_EXPORT bool Fix_UASubscribeByCustomer(HANDLE_SESSION sess, FIX_INT64 &nSubs, const char *sKHH, const char *sPwd, void *pFunc, void *pData);
FIX_API_EXPORT bool Fix_UASubscribeByCustomer_RZRQ(HANDLE_SESSION sess, FIX_INT64 &nSubs, const char *sKHH, const char *sPwd, void *pFunc, void *pData);
FIX_API_EXPORT bool Fix_UASubscribeByCustomer_SOP(HANDLE_SESSION sess, FIX_INT64 &nSubs, const char *sKHH, const char *sPwd, void *pFunc, void *pData);
FIX_API_EXPORT bool Fix_UCSubscribeByCustomer(HANDLE_SESSION sess, FIX_INT64 &nSubs, const char *sKHH, const char *sPwd, void *pFunc, void *pData);

FIX_API_EXPORT bool Fix_SubscribeQuote(HANDLE_SESSION sess, FIX_INT64 &nSubs, void *pFunc, void *pData);

// 通过申请一个新的会话句柄，来取消之前的订阅
FIX_API_EXPORT bool Fix_Unsubscribe(HANDLE_SESSION sess, FIX_INT64 nSubs);
FIX_API_EXPORT bool Fix_Unsubscribe_NoWaiting(HANDLE_SESSION sess, FIX_INT64 nSubs);

/*
函数名称: Fix_RegReplyCallFunc

函数说明:
    设置会话应答回调函数
    回调函数定义为:
    bool Func(HANDLE conn, HANDLE sess, int nResv )
        -- conn 连接句柄
        -- sess 会话句柄，NULL表示设置全部业务会话应答的回调函数；否则为指定会话的回调函数
        -- nResv 保留值

参数说明:
    sess    -- [in] 会话句柄
    pFunc   -- [in] 回调函数指针

返回结果:
    true    -- 调用成功
    false   -- 调用失败
*/
FIX_API_EXPORT bool Fix_RegReplyCallFunc(HANDLE_SESSION hSess, void *pFunc);

// 设置会话附加信息
FIX_API_EXPORT bool Fix_SetSessData(HANDLE_SESSION hSess, void *pData);

// 读取会话附加信息
FIX_API_EXPORT void *Fix_GetSessData(HANDLE_SESSION hSess);

// 设置日志路径，默认在当前路径的log目录下
FIX_API_EXPORT bool Fix_SetLogPath(const char *sPath);

// 设置日志级别 默认为0，表示记录连接日志 1，表示连接日志+通信报文日志
FIX_API_EXPORT bool Fix_SetLogLevel(int nLevel);

// 获取指定行数据的列数量，行号从0开始
FIX_API_EXPORT int Fix_GetColumnCount(HANDLE_SESSION sess, int nRow);

/*
函数名称: Fix_GetValWithIdByIndex

函数说明:
    获取指定行、指定列下的字段id号 以及相应的数据

参数说明:
    sess    -- [in] 会话句柄
    nRow    -- [in] 行序号,从零开始(配合Fix_GetCount)
    nIndex  -- [in] 列序号,从零开始(Fix_GetColumnCount)

    nFid    -- [out] 域id
    out     -- [out] 域对应的数据(内存上层分配)
    nSize   -- [in/out] out的大小，函数会输出相应的真实数据大小

返回数据:
    true    -- 成功
    false   -- 失败(比如序号越界或者out内存不足)
*/
FIX_API_EXPORT bool Fix_GetValWithIdByIndex(HANDLE_SESSION sess, int nRow, int nIndex, int &nFid, char *out, int &nSize);
FIX_API_EXPORT bool Fix_GetBody(HANDLE_SESSION sess, int nRow, char *&out_buf, int &out_len);
// 注意：该接口目前暂且只能在fix_run 或者 fix_asyncrun 后调用
FIX_API_EXPORT bool Fix_GetReqBody(HANDLE_SESSION sess, char *&out_buf, int &out_len);

FIX_API_EXPORT bool Fix_SetSystemId(HANDLE_SESSION sess, int nId);
FIX_API_EXPORT bool Fix_SetNodeId(HANDLE_SESSION sess, int nId);
FIX_API_EXPORT bool Fix_SetESB(HANDLE_SESSION sess, bool bESB);
FIX_API_EXPORT bool Fix_SetDebug(HANDLE_SESSION sess, bool bDebug);
FIX_API_EXPORT int Fix_GetSystemId(HANDLE_SESSION sess);
FIX_API_EXPORT int Fix_GetNodeId(HANDLE_SESSION sess);

FIX_API_EXPORT bool Fix_SetDefaultSystemId(int nId);
FIX_API_EXPORT bool Fix_SetDefaultNodeId(int nId);
FIX_API_EXPORT int Fix_GetDefaultSystemId();
FIX_API_EXPORT int Fix_GetDefaultNodeId();
FIX_API_EXPORT FIX_INT64 Fix_GetLastRecvTime(HANDLE_CONN conn);
FIX_API_EXPORT FIX_INT64 Fix_GetLastSendTime(HANDLE_CONN conn);
FIX_API_EXPORT char *Fix_GetConnectIp(HANDLE_CONN conn, char *out, int &io_len);

// for struct data
// req
FIX_API_EXPORT bool Fix_SetCustomerForBindThread(HANDLE_CONN conn, const char *pszKHH);
FIX_API_EXPORT bool Fix_SetStructData(HANDLE_SESSION sess, unsigned char *pData, int nSize);
// ans
FIX_API_EXPORT bool Fix_IsStruct(HANDLE_SESSION sess, int nRow = 0);
FIX_API_EXPORT bool Fix_GetStructData(HANDLE_SESSION sess, unsigned char *pData, int &nSize, int nRow = 0);
FIX_API_EXPORT unsigned char *Fix_GetStructDataEx(HANDLE_SESSION sess, int &nSize, int nRow = 0);
FIX_API_EXPORT unsigned char *Fix_GetReqStructData(HANDLE_SESSION sess, int &nSize);

// 全局订阅回调函数
// bool (*)(HANDLE, HANDLE, int64, void *)
FIX_API_EXPORT void Fix_RegGlobalPublishFunc(void *pFunc);
FIX_API_EXPORT void Fix_RegGlobalStructPublishFunc(void *pFunc);
FIX_API_EXPORT void Fix_RegStructPublishFunc(HANDLE_CONN conn, void *pFunc);

// 读取会话包序号
FIX_API_EXPORT FIX_INT64 Fix_GetPacketId(HANDLE_SESSION sess);
// 回调函数原型: bool Func(HANDLE_CONN conn, int nEvent, void* pData);
FIX_API_EXPORT bool Fix_SetConnEvent(HANDLE_CONN conn, void *pFunc, void *pData = NULL);
// 设置会话请求附加信息
// SYSINFO_IP = 0 添加IP地址信息
// SYSINFO_MAC = 1 添加MAC地址信息
FIX_API_EXPORT bool Fix_SetSysInfo(HANDLE_SESSION sess, int ntype, int id);
FIX_API_EXPORT char *Fix_GetSysInfo(int ntype, char *buf, int len, HANDLE_CONN conn = 0);

FIX_API_EXPORT const char *Fix_Version();

FIX_API_EXPORT bool Fix_SetPathTrace(HANDLE_SESSION sess, bool bval);
FIX_API_EXPORT char *Fix_GetPathTraceInfo(HANDLE_SESSION sess, char *out, int &io_len);
FIX_API_EXPORT bool Fix_SetStatTraceInfo(HANDLE_SESSION sess, const char *str);
FIX_API_EXPORT char *Fix_GetStatTraceInfo(HANDLE_SESSION sess, char *out, int &io_len);

// 获取证书有效期
//@filepath 证书文件路径 PKCS12打包的客户端证书文件
//@pwd 证书密码
//@start 起始时间 UTC时间, 从1970年1月1日00:00:00 计算的秒数
//@end	结束时间
//@return 0.成功 -1.读取证书文件失败 -2.读取证书信息失败
FIX_API_EXPORT int Fix_GetCertValidPeriod(const char *filepath, const char *pwd, FIX_INT64 &start, FIX_INT64 &end);

FIX_API_EXPORT bool Fix_AddBody(HANDLE_SESSION hSess, char *pdata, int len);

// 返回值, 0.成功, -1.未找到该key的正则表达式, -2.匹配失败, -3.入参为NULL, -4.正则表达错误
FIX_API_EXPORT int Fix_RegexMatch(const char *key, const char *val);

// 返回值, 0.成功, -1.未找到key为"addr"的正则表达式, -2.匹配失败, -3.入参为NULL, -4.正则表达错误
FIX_API_EXPORT int Fix_RegexMatchAddr(const char *val);

// 保留,非交易,设置缺省的区域代码(4位长度字符串)
#define Fix_SetDefaultRegionCode Fix_SetDefaultQYBM
FIX_API_EXPORT bool Fix_SetDefaultQYBM(const char *sQYBM);

#endif // __APEX_FIXAPI_H__